/**
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// NOTE autogenerated file

const RESULT: any = {}

function preparePersist(x: any): any {
% ESChecker::UNMANGLE.each { |k, v|
%   if v != "NaN"
  if (x === <%= v %>) {
    return "<%= k %>";
  }
%   end
% }
  if (typeof x === "number" && isNaN(x)) {
    return "#__NaN"
  }
  if (typeof x === "string") {
    if ((x as any).isWellFormed()) {
      return x;
    }
    const ret = []
    for (let i = 0; i < x.length; i++) {
      ret.push(x.charCodeAt(i))
    }
    return { "__kind": "str", "data": ret }
  }
  if (x instanceof Array) {
    return (x as Array<any>).map(preparePersist)
  }
  if (typeof x[Symbol.iterator] === 'function') {
    return Array.from<any>(x).map(preparePersist)
  }
  if (x instanceof DataView) {
    const arr = new Array<number>()
    for (let i = 0; i < x.byteLength; i++) {
      arr.push(x.getUint8(i))
    }
    return arr;
  }
  if (typeof x === "bigint") {
    return {
      "__kind": "bigint",
      "data": x.toString()
    }
  }
  return x;
}

function persistValue(x: any): any {
  const y = preparePersist(x);
  if (typeof y === "number") {
    return y;
  }
  return JSON.parse(JSON.stringify(y));
}

<%= test_cases_current_chunk[0]&.conf&.top_scope %>

{
% test_cases_current_chunk.each_with_index { |test_case_cur, idx|
{
  // <%= idx %>
%   if test_case_cur.self
  const self = <%= test_case_cur.ts.self %>;
%   end
  <%= test_case_cur.conf.setup %>

  try {
    RESULT[<%= idx * 2 %>] = persistValue(<%= test_case_cur.ts.expr %>);
  } catch (e) {
    RESULT[<%= idx * 2 %>] = "#__threw " + String(e);
  }
%   if test_case_cur.self
    RESULT[<%= idx * 2 + 1 %>] = persistValue(self);
%   end
}
% }
}

const numPrec = (k: any, v: any) => {
  if (typeof v === "number") {
    if (Number.isInteger(v)) {
      return v;
    }
    const x = new DataView(new ArrayBuffer(8))
    x.setFloat64(0, v, true)
    const bi = x.getBigUint64(0, true)
    const arr = new Array<number>()
    for (let i = 0; i < x.byteLength; i++) {
      const byte = (bi / (1n << BigInt(i * 8))) % 256n
      arr.push(Number(byte))
    }
    const toPut = arr.map((b, i) => `(0x${b.toString(16).padStart(2, '0')} as long) << ${i * 8}`)
    return {
      "__kind": "num",
      "data": toPut.join(' | '),
      "dbg": v.toFixed(100).replace(/(\.[0-9]*[1-9]+)(0*)$/, '$1')
    }
  }
  return v;
}

console.log(JSON.stringify(RESULT, numPrec))
